package com.guaoran.source.spring.framework.aop;

import java.lang.reflect.Field;
import java.lang.reflect.Proxy;

/**
 * @author : 孤傲然
 * @Description :
 *  AOP代理工具类
 *  将代理后的类转换成原始类
 * @date :2018/7/4 8:41
 */
public class AopProxyUtils {
    /**
     * 根据代理类获得原始类
     * @param aopProxy
     * @return
     * @throws Exception
     */
    public static Object getTargetObject(Object aopProxy) throws Exception {
        //判断该对象是否是代理类,如果不是，则直接返回
        if(!isAopProxy(aopProxy)){return aopProxy;}
        return getProxyTargetObject(aopProxy);

    }

    /**
     * 判断是否是一个代理类
     * @param object
     * @return
     */
    private static boolean isAopProxy(Object object){
        return Proxy.isProxyClass(object.getClass());
    }

    /**
     * 根据代理类获得原始类
     * @param proxy
     * @return
     * @throws Exception
     */
    private static Object getProxyTargetObject(Object proxy) throws Exception{
        //获得h的属性信息，即存储了原始类的字段
        Field h = proxy.getClass().getSuperclass().getDeclaredField("h");
        //设置强制访问
        h.setAccessible(true);
        AopProxy aopProxy = (AopProxy) h.get(proxy);
        Field target = aopProxy.getClass().getDeclaredField("target");
        target.setAccessible(true);
        return target.get(aopProxy);
    }
}
